package cn.com.utt.unms.aspect;

import java.lang.reflect.Method;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import cn.com.utt.common.log.SaveIpaddress;
import cn.com.utt.common.log.doLog;
import cn.com.utt.common.util.LocaleMessageSourceUtil;
import cn.com.utt.common.util.Tips;
import cn.com.utt.common.vo.RestResult;
import cn.com.utt.common.vo.User;
import cn.com.utt.unms.pojo.Log;
import cn.com.utt.unms.service.LogService;

@Aspect
@Component
public class SaveLog {
	@Autowired
	private LogService logService;
	
	@Autowired
    private LocaleMessageSourceUtil messageSourceUtil;
	
	

	@Pointcut("execution(* cn.com.utt.unms.service.impl.RfServiceImpl.*(..))")
	public void RfServiceImpl() {

	}

	@Pointcut("execution(* cn.com.utt.unms.service.impl.DeviceServiceImpl.*(..))")
	public void DeviceServiceImpl() {

	}

	@Pointcut("execution(* cn.com.utt.unms.service.impl.WirelessServiceImpl.*(..))")
	public void WirelessServiceImpl() {

	}

	@Pointcut("execution(* cn.com.utt.unms.service.impl.GroupServiceImpl.*(..))")
	public void GroupServiceImpl() {

	}

	@Pointcut("execution(* cn.com.utt.unms.service.impl.NetworkServiceImpl.*(..))")
	public void NetworkServiceImpl() {

	}

	@Pointcut("execution(* cn.com.utt.common.service.impl.UserServiceImpl.*(..))")
	public void UserServiceImpl() {

	}

	@Pointcut("execution(* cn.com.utt.unms.service.impl.AccountServiceImpl.*(..))")
	public void AccountServiceImpl() {

	}

	private static String parseKey(String key, Method method, Object[] args) {

		// 获取被拦截方法参数名列表(使用Spring支持类库)
		LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
		String[] paraNameArr = u.getParameterNames(method);

		// 使用SPEL进行key的解析
		ExpressionParser parser = new SpelExpressionParser();
		// SPEL上下文
		StandardEvaluationContext context = new StandardEvaluationContext();
		// 把方法参数放入SPEL上下文中
		for (int i = 0; i < paraNameArr.length; i++) {
			context.setVariable(paraNameArr[i], args[i]);
		}
		return parser.parseExpression(key).getValue(context, String.class);
	}

	@AfterReturning(pointcut = "AccountServiceImpl()||UserServiceImpl()||NetworkServiceImpl()||RfServiceImpl()||DeviceServiceImpl()||WirelessServiceImpl()||GroupServiceImpl()", returning = "result")
	public void doAfter(JoinPoint point, RestResult result) {
		try {
			doLog dolog = null;
			String classname = point.getTarget().getClass().getName();
			String methodName = point.getSignature().getName();
			Object[] arguments = point.getArgs();
			Class targetClass = Class.forName(classname);
			Method method = null;
			Method[] methods = targetClass.getMethods();
			for (Method m : methods) {
				if (m.getName().equals(methodName)
						&& m.getAnnotation(doLog.class) != null) {
					method = m;
				}
			}
			if (method != null) {
				dolog=method.getAnnotation(doLog.class);
				SecurityContext context = SecurityContextHolder.getContext();
				Authentication authentication = context.getAuthentication();
				if (authentication != null && !authentication.getPrincipal().equals("anonymousUser")) {
					User user = (User) authentication.getPrincipal();
					if (!dolog.key()[0].equals("")) {
						String[] k = dolog.key();
						String key = "";
						for (int i = 0; i < k.length; i++) {
							if (i == k.length - 1) {
								key = key + parseKey(k[i], method, arguments);
							} else {
								key = key + parseKey(k[i], method, arguments)
										+ ",";
							}
						}
						Date date = new Date();
						Log log = new Log();
						log.setUserId(user.getId());
						log.setContent(messageSourceUtil.getMessage(dolog.description()) + key);
						log.setDate(date);
						String ipaddress = SaveIpaddress.getThreadLocal().get();
						log.setIpaddress(ipaddress);
						if (result.getErrorCode() == 0) {
							log.setState(0);
							logService.save(log);
						} else {
							//log.setState(1);
							//logService.save(log);
						}

					} else {
						Date date = new Date();
						Log log = new Log();
						String ipaddress = SaveIpaddress.getThreadLocal().get();
						log.setIpaddress(ipaddress);
						log.setUserId(user.getId());
						log.setContent(messageSourceUtil.getMessage(dolog.description()));
						log.setDate(date);
						if (result.getErrorCode() == 0) {
							log.setState(0);
							logService.save(log);
						} else {
							log.setState(1);
							logService.save(log);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
